home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / comm / comm1 / statty31.lha / statty / statty.rexx < prev   
OS/2 REXX Batch file  |  1996-12-23  |  27KB  |  910 lines

  1. /*
  2. ** $VER: statty.rexx 3.1 (23.12.96) Rolf Rotvel
  3. **
  4. ** Uses rexxtricks.library, locale.library and rexxlocaldates.library
  5. */ 
  6.  
  7. area.mmtaglen = 30              /* In MM log tagnames are cut off after x chars */
  8. path.cfg = 'mail:statty.cfg'    /* Default path to cfg file */
  9.  
  10. /*
  11. ** Initializing
  12. */
  13.  
  14. signal on syntax
  15. signal on error
  16.  
  17. /* Load libraries */
  18. call addlib('rexxsupport.library', 0, -30, 0)
  19. call addlib('rexxtricks.library', 0, -30, 0)
  20. call addlib('locale.library', 0, -30, 0)
  21. call addlib('rexxlocaldates.library', 0, -30, 0)
  22.  
  23. /* Parse argument - if any */
  24. if arg() > 0 then do
  25.     parse arg path.cfg
  26.     if path.cfg = '?' then do 
  27.         options prompt 'CONFIGFILE: '
  28.         parse pull path.cfg
  29.         if path.cfg = '' then exit
  30.     end
  31. end
  32.  
  33. /* Get localized error strings */
  34. cat = opencatalog('statty.catalog', 'english',)
  35. msg.err_cfg = getcatalogstr(cat, 1, "Couldn't read configfile:")
  36. msg.err_tosser = getcatalogstr(cat, 2, "Statty doesn't support:")
  37. call closecatalog(cat)
  38.  
  39. /* Read & parse cfg file */
  40. if ~readfile(path.cfg, cfg) then call errorexit(msg.err_cfg||' "'||path.cfg||'"')
  41. do c = 1 to cfg.0
  42.     interpret cfg.c
  43. end
  44. drop cfg.
  45.  
  46. /* Check tosser */
  47. uptosser = upper(tosser)
  48. select
  49.     when uptosser = 'FOOZLE' then nop
  50.     when uptosser = 'SPOT' then nop
  51.     when uptosser = 'MAILMANAGER' then nop
  52.     when uptosser = 'CRASHMAIL' then do
  53.         toyou? = 0  /* CrashMail doesn't log letters to sysop */
  54.     end
  55.     otherwise call errorexit(msg.err_tosser||' "'||tosser||'"')
  56. end
  57.  
  58. /* Get rest of error strings */
  59. cat = opencatalog('statty.catalog', 'english',)
  60. msg.err_read = getcatalogstr(cat, 3, "Couldn't read")
  61. msg.err_find = getcatalogstr(cat, 4, "Couldn't find")
  62. msg.err_del = getcatalogstr(cat, 5, "Couldn't delete")
  63. msg.err_create = getcatalogstr(cat, 6, "Couldn't create")
  64. msg.err_write = getcatalogstr(cat, 7, "Couldn't write")
  65.  
  66. /* Message strings */
  67. if keeplog? then msg.bak_log = getcatalogstr(cat, 20, 'Backing up log to')
  68.  
  69. msg.no_msgs = getcatalogstr(cat, 21, 'No new messages to process')
  70. msg.read = getcatalogstr(cat, 22, 'Reading')
  71. msg.fin = getcatalogstr(cat, 23, 'Finished')
  72. msg.calcdb = getcatalogstr(cat, 26, 'Calculating database')
  73. msg.write = getcatalogstr(cat, 27, 'Writing')
  74.  
  75. if tosser = 'MailManager' then msg.dup_area = getcatalogstr(cat, 25, 'added to')
  76. else do
  77.     msg.dup_area = getcatalogstr(cat, 24, 'Found areaname "%s" twice in')
  78.     if tosser = 'Spot' then do
  79.         msg.xport_start = getcatalogstr(cat, 28, 'Export started')
  80.         msg.xport_end = getcatalogstr(cat, 29, 'Export ended')
  81.     end
  82. end
  83.  
  84. /* Strings used in outputfile */
  85. msg.out_1 = getcatalogstr(cat, 100, 'echomail database created by Statty')
  86. msg.out_2 = getcatalogstr(cat, 101, 'Database was started:')
  87. msg.out_3 = getcatalogstr(cat, 102, 'Messages in database:')
  88. msg.out_4 = getcatalogstr(cat, 103, 'to you')
  89. msg.out_5 = getcatalogstr(cat, 104, 'from you')
  90. msg.out_6 = getcatalogstr(cat, 105, 'This update')
  91. msg.out_7 = getcatalogstr(cat, 106, 'Last update')
  92. msg.out_8 = getcatalogstr(cat, 107, 'new messages')
  93. msg.out_9 = getcatalogstr(cat, 108, 'in %s areas')
  94. msg.out_10 = getcatalogstr(cat, 109, 'Areas')
  95. msg.out_11 = getcatalogstr(cat, 110, 'Total')
  96. msg.out_12 = getcatalogstr(cat, 111, 'New')
  97. call closecatalog(cat)
  98.  
  99. /* Check paths */
  100. if ~exists(path.log) then call errorexit(msg.err_find||' '||path.log)
  101. if ~exists(path.area) then call errorexit(msg.err_find||' '||path.area)
  102.  
  103. /*
  104. ** Main
  105. */
  106.  
  107. /* Datestamp */ 
  108. start.thisdb = date('i')||'.'||time('s')
  109.  
  110. /* Multitasking... */
  111. call pragma('p', -1)
  112.  
  113. /* Backup logfile */
  114. if keeplog? then do
  115.     if path.keeplog ~= '' then oldpath = makepath(pathpart(path.log), path.keeplog)
  116.     else oldpath = path.log||'.statty'
  117.  
  118.     say msg.bak_log||' '||oldpath
  119.  
  120.     if exists(oldpath) then call copyfile(path.log, oldpath, 'a')
  121.     else call copyfile(path.log, oldpath, 'c')
  122. end
  123.  
  124. /* Read excludefile */
  125. if path.exc = '' then path.exc = makepath(pathpart(path.db), 'statty.exclude')
  126. if ~readfile(path.exc, area.exc) then area.exc.0 = 0
  127.  
  128. /* Parse db and area files */
  129. if exists(path.db) then do
  130.     say msg.read||' '||path.db
  131.     if ~readfile(path.db, line) then call errorexit(msg.err_read||' '||path.db)
  132.     parse var line.1 start.firstdb start.lastdb start.areastamp .
  133.  
  134.     parse value statef(path.area) with . . . . days mins ticks .
  135.     chkstamp = days||mins||ticks
  136.  
  137.     if start.areastamp ~= chkstamp then do
  138.         start.areastamp = chkstamp
  139.  
  140.         interpret 'call '||tosser||'area()'
  141.  
  142.         num = 1
  143.         do d = 2 to line.0
  144.             parse var line.d _msgs '"' _name '"' _toyou _fromyou  .
  145.             db.name.num = _name
  146.             db.msgs.num = _msgs
  147.             db.toyou.num = _toyou
  148.             db.fromyou.num = _fromyou
  149.             say count(num)
  150.             num = num + 1
  151.         end
  152.         db.name.0 = num - 1
  153.  
  154.     end
  155.     else do 
  156.         num = 1
  157.         do d = 2 to line.0
  158.             parse var line.d _msgs '"' _name '"' _toyou _fromyou  .
  159.  
  160.             if area.exc.0 > 0 then do
  161.                 if lsearch(_name, area.exc) ~= -1 then iterate
  162.             end
  163.             
  164.             area.name.num = _name
  165.             db.name.num = _name
  166.             db.msgs.num = _msgs
  167.             db.toyou.num = _toyou
  168.             db.fromyou.num = _fromyou
  169.             say count(num)
  170.             num = num + 1
  171.         end
  172.         area.name.0 = num - 1
  173.         db.name.0 = area.name.0
  174.     end
  175. end
  176. else do
  177.     interpret 'call '||tosser||'area()'
  178.  
  179.     start.firstdb = start.thisdb
  180.     start.lastdb = start.thisdb
  181.  
  182.     parse value statef(path.area) with . . . . days mins ticks .
  183.     start.areastamp = days||mins||ticks
  184.  
  185.     do a = 1 to area.name.0
  186.         db.name.a = area.name.a
  187.         db.msgs.a = 0 
  188.         db.toyou.a = 0
  189.         db.fromyou.a = 0
  190.     end
  191. end
  192.  
  193. /* Parse log file */
  194. log.name.0 = 0
  195. interpret 'call '||tosser||'log()'
  196. if log.name.0 = 0 then say msg.no_msgs
  197. else do
  198.     call calculatedb()    /* Calculate database */
  199.     call putdb()          /* Write database */
  200.     call genoutput()      /* Write output */
  201. end
  202. if ~delete(path.log) then call errorexit(msg.err_del||' '||path.log)
  203. say msg.fin
  204. exit
  205.  
  206.  
  207. ERROREXIT: 
  208. say arg(1) 
  209. exit 10
  210.  
  211.  
  212. SPOTAREA: procedure expose area. msg. path.
  213. say msg.read||' '||path.area
  214. if ~readfile(path.area, line) then call errorexit(msg.err_read||' '||path.area)
  215.  
  216. num = 1
  217.  
  218. do a = 1 to line.0
  219.     chk = upper(line.a)
  220.  
  221.     /* Skip separator, bad, default & netmail areas */
  222.     if pos(' SEPARATOR', chk) > 0 | pos(' BAD', chk) > 0 |,
  223.        pos(' DEFAULT', chk) > 0 | pos(' NETMAIL', chk) > 0 then iterate
  224.     parse var line.a . '"' . '"' '"' _user '"'
  225.  
  226.     /* Is areaname in excludefile? */
  227.     if area.exc.0 > 0 then do
  228.         if lsearch(_user, area.exc) ~= -1 then iterate
  229.     end
  230.  
  231.     /* A duplicate (user) areaname?!? */
  232.     if lsearch(_user, area.name) ~= -1 then call errorexit,
  233.         (replace(msg.dup_area, '%s', _user)||' '||path.area||'!')
  234.  
  235.     area.name.num = _user
  236.     area.name.0 = num       /* Needed for lsearch() */                    
  237.     say count(num)
  238.     num = num + 1
  239.  
  240. end
  241. return
  242.  
  243.  
  244. FOOZLEAREA: procedure expose area. msg. path.
  245. say msg.read||' '||path.area
  246. if ~open('tmp', path.area, 'r') then call errorexit(msg.err_read||' '||path.area)
  247.  
  248. num = 1
  249. null = '0'x
  250.  
  251. do forever
  252.     _name = readch('tmp', 24)                           /* Read areaname */
  253.     if eof('tmp') then leave                            /* Break condition */
  254.     tag = upper(strip(readch('tmp', 24), 't', null))    /* Read tagname */
  255.     dir = compress(readch('tmp', 32), null)             /* Read areadir */
  256.     call seek('tmp', 128 + 520)                         /* Skip rest of area definition */
  257.                                                         /* Iterate if not valid area ? */
  258.     if dir = '' | ~exists(dir) | tag = 'BAD' |,     
  259.        tag = 'MATRIX' then iterate
  260.  
  261.     _name = strip(_name, 't', null)
  262.  
  263.     /* Is areaname in excludefile? */
  264.     if area.exc.0 > 0 then do
  265.         if lsearch(_name, area.exc) ~= -1 then iterate
  266.     end
  267.  
  268.                                                         /* A duplicate areaname?!? */
  269.     if lsearch(_name, area.name) ~= -1 then call errorexit,
  270.         (replace(msg.dup_area, '%s', _name)||' '||path.area||'!')
  271.  
  272.  
  273.     area.name.num = _name
  274.     area.name.0 = num                                   /* Needed for lsearch() */
  275.     say count(num)
  276.     num = num + 1
  277. end
  278.  
  279. call close('tmp')
  280. return
  281.  
  282.  
  283. MAILMANAGERAREA: procedure expose area. msg. path.
  284. say msg.read||' '||path.area
  285. if ~readfile(path.area, line) then call errorexit(msg.err_read||' '||path.area)
  286.  
  287. num = 1
  288. start = 1
  289.  
  290. do forever
  291.     /* Skip bad, netmail, fileecho & tick areas */
  292.     a = lsearch("'#ECHOAREA #?", line, start,, pattern)
  293.     if a = -1 then leave            
  294.     start = a + 1
  295.  
  296.     parse var line.a . '"' . '"' _name .
  297.  
  298.     /* Is areaname in excludefile? */
  299.     if area.exc.0 > 0 then do
  300.         if lsearch(_name, area.exc) ~= -1 then iterate
  301.     end
  302.  
  303.     if length(_name) > area.mmtaglen then do
  304.         subname = left(_name, area.mmtaglen)
  305.         chk = lsearch(subname||'#?', area.name,,, 'p') 
  306.         if chk ~= -1 then do         
  307.             say '"'||_name||'" '||msg.dup_area||' '||path.exc
  308.             if area.exc.0 > 0 then call open('tmp', path.exc, 'a') 
  309.             else do
  310.                 if ~open('tmp', path.exc, 'w') then call errorexit(msg.err_create||' '||path.exc)
  311.                 area.exc.0 = 1
  312.             end
  313.             call writeln('tmp', _name)
  314.             call close('tmp')
  315.         end
  316.     end
  317.  
  318.     area.name.num = _name
  319.     area.name.0 = num
  320.     say count(num)
  321.     num = num + 1
  322. end
  323. return
  324.  
  325.  
  326. CRASHMAILAREA: procedure expose area. msg. path.
  327. say msg.read||' '||path.area
  328. if ~readfile(path.area, line) then call errorexit(msg.err_read||' '||path.area)
  329.  
  330. num = 1
  331. start = 1
  332.  
  333. do forever
  334.     /* Skip bad, netmail, fileecho & tick areas */
  335.     a = lsearch("AREA #?", line, start,, pattern)
  336.     if a = -1 then leave            
  337.     start = a + 1
  338.  
  339.     parse var line.a . _name .
  340.     upname = upper(name)
  341.     if upname = 'BAD' | upname = 'DEFAULT' then iterate
  342.  
  343.     /* Is areaname in excludefile? */
  344.     if area.exc.0 > 0 then do
  345.         if lsearch(_name, area.exc) ~= -1 then iterate
  346.     end
  347.  
  348.     area.name.num = _name
  349.     area.name.0 = num
  350.     say count(num)
  351.     num = num + 1
  352. end
  353. return
  354.  
  355.  
  356. SPOTLOG: procedure expose log. area. msg. path.
  357. say msg.read||' '||path.log
  358. if ~readfile(path.log, line) then call errorexit(msg.err_read||' '||path.log)
  359.  
  360. num = 1
  361. export? = 0
  362. counter = 1
  363.  
  364. do l = 1 to line.0
  365.     first = left(line.l, 1)
  366.     select
  367.         when pos(msg.xport_start, line.l) > 0 then export? = 1
  368.         when pos(msg.xport_end, line.l) > 0 then export? = 0
  369.         when first = '*' | first = '!' then do
  370.             parse var line.l . "'" _name "'" rest
  371.  
  372.             /* Iterate if it's not a valid areaname */
  373.             if lsearch(_name, area.name) = -1 then iterate
  374.             
  375.             /* Find amount of msgs imported */
  376.             wds = words(rest)
  377.             do w = 1 to wds
  378.                 _msgs = word(rest, w)
  379.                 if datatype(_msgs, 'w') then leave
  380.             end
  381.  
  382.             /* Parse rest of line if any msgs for you */
  383.             if ~export? then do
  384.                 if first = '*' then do ww = w + 1 to wds
  385.                     _toyou = word(rest, ww)
  386.                     if datatype(_toyou, 'w') then leave
  387.                 end
  388.                 else _toyou = 0
  389.  
  390.                 /* Is it first time we find this areaname in logfile? */
  391.                 chk = lsearch(_name, log.name)
  392.                 if chk = -1 then do         /* Initialize variables */
  393.                     log.name.num = _name
  394.                     log.msgs.num = _msgs
  395.                     log.toyou.num = _toyou
  396.                     log.fromyou.num = 0
  397.                     log.name.0 = num        /* Need this for lsearch() */
  398.                     num = num + 1
  399.                 end
  400.                 else do                     /* Update variables */
  401.                     log.msgs.chk = log.msgs.chk + _msgs
  402.                     log.toyou.chk = log.toyou.chk + _toyou
  403.                 end
  404.                 say count(counter)
  405.                 counter = counter + 1
  406.             end
  407.             else do /* Export! */
  408.                 chk = lsearch(_name, log.name)
  409.                 if chk = -1 then do         /* Initialize variables */
  410.                     log.name.num = _name
  411.                     log.msgs.num = _msgs
  412.                     log.toyou.num = 0
  413.                     log.fromyou.num = _msgs
  414.                     log.name.0 = num        /* Need this for lsearch() */
  415.                     num = num + 1
  416.                 end
  417.                 else do                     /* Update variables */
  418.                     log.msgs.chk = log.msgs.chk + _msgs
  419.                     log.fromyou.chk = log.fromyou.chk + _msgs
  420.                 end
  421.                 say count(counter)
  422.                 counter = counter + 1
  423.             end
  424.         end
  425.         otherwise nop
  426.     end
  427. end
  428. return
  429.  
  430.  
  431. FOOZLELOG: procedure expose log. area. path. msg.
  432. say msg.read||' '||path.log
  433. if ~readfile(path.log, line) then call errorexit(msg.err_read||' '||path.log)
  434.  
  435. num = 1
  436.  
  437. do l = 1 to line.0
  438.     if word(line.l, 4) = 'Area' then do
  439.         parse var line.l . '"' _name '"' rest
  440.         /* Iterate if it's not a valid areaname */
  441.         if lsearch(_name, area.name) = -1 then iterate
  442.         /* Find amount of msgs imported */
  443.         wds = words(rest)
  444.         do w = 1 to wds
  445.             _msgs = word(rest, w)
  446.             if datatype(_msgs, 'w') then leave
  447.         end
  448.  
  449.         /* Parse rest of line if any msgs for you */
  450.         if right(line.l, 7) = 'for you' then do ww = w + 1 to wds
  451.             _toyou = word(rest, ww)
  452.             if datatype(_toyou, 'w') then leave
  453.         end
  454.         else _toyou = 0
  455.  
  456.         /* Is it first time we find this areaname in logfile? */
  457.         chk = lsearch(_name, log.name)
  458.         if chk = -1 then do         /* Initialize variables */
  459.             log.name.num = _name
  460.             log.msgs.num = _msgs
  461.             log.toyou.num = _toyou
  462.             log.fromyou.num = 0     /* Foozle doesn't support this...*/
  463.             log.name.0 = num        /* Need this for lsearch() */
  464.             num = num + 1
  465.         end
  466.         else do                     /* Update variables */
  467.             log.msgs.chk = log.msgs.chk + _msgs
  468.             log.toyou.chk = log.toyou.chk + _toyou
  469.         end
  470.         say count(counter)
  471.         counter = counter + 1
  472.     end
  473. end
  474. return
  475.  
  476.  
  477. MAILMANAGERLOG: procedure expose log. area. msg. path.
  478. say msg.read||' '||path.log
  479. if ~readfile(path.log, line) then call errorexit(msg.err_read||' '||path.log)
  480.  
  481. num = 1
  482.  
  483. startimp = 'Import Statistics'
  484. endimp   = 'Import Used'
  485.  
  486. startexp = 'Start Export Function'
  487. endexp   = 'End Export Function'
  488.  
  489. action = ''
  490. counter = 1
  491.  
  492. do l = 1 to line.0
  493.     if action = '' then do
  494.         select
  495.             when pos(startimp, line.l) > 0 then action = 'imp'
  496.             when pos(startexp, line.l) > 0 then action = 'exp'
  497.             otherwise nop
  498.         end
  499.     end
  500.     else do
  501.         select
  502.             when pos(endimp, line.l) > 0 then action = ''
  503.             when pos(endexp, line.l) > 0 then action = ''
  504.             when word(line.l, 7) = 'Area' then do
  505.                 if action = 'imp' then do
  506.                     parse var line.l . 'Area' _name _msgs '(' _toyou ')'
  507.  
  508.                     /* Iterate if it's not a valid areaname */
  509.                     if length(_name) < area.mmtaglen then chk = lsearch(_name, area.name)
  510.                     else chk = lsearch(_name||'#?', area.name,,, 'p')
  511.                     if chk = -1 then iterate
  512.  
  513.                     _msgs = strip(_msgs)
  514.                     _toyou = strip(_toyou)
  515.  
  516.                     /* Is it first time we find this areaname in logfile? */
  517.                     chk = lsearch(_name, log.name)
  518.                     if chk = -1 then do         /* Initialize variables */
  519.                         log.name.num = _name
  520.                         log.msgs.num = _msgs
  521.                         log.toyou.num = _toyou
  522.                         log.fromyou.num = 0
  523.                         log.name.0 = num        /* Need this for lsearch() */
  524.                         num = num + 1
  525.                     end
  526.                     else do                     /* Update variables */
  527.                         log.msgs.chk = log.msgs.chk + _msgs
  528.                         log.toyou.chk = log.toyou.chk + _toyou
  529.                     end
  530.                     say count(counter)
  531.                     counter = counter + 1
  532.                 end
  533.                 else do     /* Standalone export */
  534.                     parse var line.l . 'Area' _name _fromyou .
  535.  
  536.                     if length(_name) < area.mmtaglen then chk = lsearch(_name, area.name)
  537.                     else chk = lsearch(_name||'#?', area.name,,, 'p')
  538.                     if chk = -1 then iterate
  539.     
  540.                     chk = lsearch(_name, log.name)
  541.                     if chk = -1 then do         /* Initialize variables */
  542.                         log.name.num = _name
  543.                         log.msgs.num = _fromyou
  544.                         log.toyou.num = 0
  545.                         log.fromyou.num = _fromyou
  546.                         log.name.0 = num        /* Need this for lsearch() */
  547.                         num = num + 1
  548.                     end
  549.                     else do                     /* Update variables */
  550.                         log.msgs.chk = log.msgs.chk + _fromyou
  551.                         log.fromyou.chk = log.fromyou.chk + _fromyou
  552.                     end
  553.                     say count(counter)
  554.                     counter = counter + 1
  555.                 end
  556.             end
  557.             otherwise nop
  558.         end
  559.     end
  560. end
  561. return
  562.  
  563.  
  564. CRASHMAILLOG: procedure expose log. area. path. msg.
  565. say msg.read||' '||path.log
  566. if ~readfile(path.log, line) then call errorexit(msg.err_read||' '||path.log)
  567.  
  568. num = 1
  569. counter = 1
  570.  
  571. do l = 1 to line.0
  572.     if word(line.l, 4) = 'Area' then do
  573.         parse var line.l . . . . _name . _msgs .
  574.         /* Iterate if it's not a valid areaname */
  575.         if lsearch(_name, area.name) = -1 then iterate
  576.  
  577.         /* Is it first time we find this areaname in logfile? */
  578.         chk = lsearch(_name, log.name)
  579.         if chk = -1 then do         /* Initialize variables */
  580.             log.name.num = _name
  581.             log.msgs.num = _msgs
  582.             log.toyou.num = 0       /* CrashMail doesn't support this...*/
  583.             log.fromyou.num = 0     /* CrashMail doesn't support this...*/
  584.             log.name.0 = num        /* Need this for lsearch() */
  585.             num = num + 1
  586.         end
  587.         else log.msgs.chk = log.msgs.chk + _msgs   /* Update variable */
  588.         say count(counter)
  589.         counter = counter + 1
  590.     end
  591. end
  592. return
  593.  
  594.  
  595. CALCULATEDB: procedure expose area. msg. log. db.
  596. say msg.calcdb
  597.  
  598. area.length = 0
  599.  
  600. area.maxmsgs = 0
  601. area.maxtoyou = 0
  602. area.maxnewmsgs = 0
  603. area.maxnewtoyou = 0
  604. area.maxfromyou = 0
  605. area.maxnewfromyou = 0
  606.  
  607. area.totalmsgs = 0
  608. area.totaltoyou = 0
  609. area.totalfromyou = 0
  610.  
  611. area.totallogmsgs = 0
  612. area.totallogtoyou = 0
  613. area.totallogfromyou = 0
  614.  
  615. do a = 1 to area.name.0
  616.     say count(a)
  617.  
  618.     chklog = lsearch(area.name.a, log.name)
  619.     if chklog = -1 then do 
  620.         newmsgs = 0
  621.         newtoyou = 0
  622.         newfromyou = 0
  623.     end
  624.     else do
  625.         newmsgs = log.msgs.chklog
  626.         newtoyou = log.toyou.chklog
  627.         newfromyou = log.fromyou.chklog
  628.     end
  629.  
  630.     chkdb = lsearch(area.name.a, db.name)
  631.     if chkdb = -1 then do 
  632.         dbmsgs = 0
  633.         dbtoyou = 0
  634.         dbfromyou = 0
  635.     end
  636.     else do
  637.         dbmsgs = db.msgs.chkdb
  638.         dbtoyou = db.toyou.chkdb
  639.         dbfromyou = db.fromyou.chkdb
  640.     end
  641.  
  642.     _msgs = newmsgs + dbmsgs
  643.     _toyou = newtoyou + dbtoyou
  644.     _fromyou = newfromyou + dbfromyou
  645.  
  646.     area.totallogmsgs = area.totallogmsgs + newmsgs
  647.     area.totallogtoyou = area.totallogtoyou + newtoyou
  648.     area.totallogfromyou = area.totallogfromyou + newfromyou
  649.  
  650.     area.totalmsgs = area.totalmsgs + _msgs
  651.     area.totaltoyou = area.totaltoyou + _toyou
  652.     area.totalfromyou = area.totalfromyou + _fromyou
  653.  
  654.     area.length = max(area.length, length(area.name.a))
  655.  
  656.     db.string.a = _msgs||' "'||area.name.a||'" '||_toyou||' '||_fromyou
  657.     area.string.a = db.string.a||' '||newmsgs||' '||newtoyou||' '||newfromyou
  658.  
  659.     /* These variables needed when calculating/formatting output */
  660.     area.maxmsgs = max(_msgs, area.maxmsgs)
  661.     area.maxtoyou = max(_toyou, area.maxtoyou)
  662.     area.maxfromyou = max(_fromyou, area.maxfromyou)
  663.  
  664.     area.maxnewmsgs = max(newmsgs +  newtoyou, area.maxnewmsgs)
  665.     area.maxnewtoyou = max(newtoyou, area.maxnewtoyou)
  666.     area.maxnewfromyou = max(newfromyou, area.maxnewfromyou)
  667.  
  668. end
  669. db.string.0 = area.name.0
  670. area.string.0 = area.name.0
  671.  
  672. drop log.
  673. return
  674.  
  675.  
  676. PUTDB: procedure expose db. start. msg. path.
  677. say msg.write||' '||path.db
  678.  
  679. line = start.firstdb||' '||start.thisdb||' '||start.areastamp
  680. call steminsert(db.string, 1,, line)
  681.  
  682. if ~writefile(path.db, db.string) then call errorexit(msg.err_write||' '||path.db)
  683.  
  684. drop db.
  685. return 
  686.  
  687.  
  688. GENOUTPUT: procedure expose start. area. msg. path. tosser toyou? allareas?
  689. say msg.write||' '||path.out
  690.  
  691. /* Convert datestamps to normal dates */
  692. template = '%e %B %Y %R'
  693. loc = openlocale()
  694.  
  695. parse var start.thisdb ds.days '.' ds.seconds
  696. start.thisdb = strip(formatdate(loc, ds, template))
  697.  
  698. if start.firstdb ~= start.thisdb then do
  699.     parse var start.firstdb ds.days '.' ds.seconds
  700.     start.firstdb = strip(formatdate(loc, ds, template))
  701.  
  702.     parse var start.lastdb ds.days '.' ds.seconds
  703.     start.lastdb = strip(formatdate(loc, ds, template))
  704. end
  705. else do
  706.     start.firstdb = start.thisdb
  707.     start.lastdb = start.thisdb
  708. end
  709.  
  710. call closelocale(loc)
  711.  
  712. /* Sort areas */
  713. call qsort(area.string,, 'num', 1)
  714.  
  715. if area.totalfromyou > 0 then fromyou? = 1
  716. else fromyou? = 0
  717.  
  718. msg_len = length(area.maxmsgs)       
  719. newmsg_len = length(area.maxnewmsgs)
  720.  
  721. if toyou? then do
  722.     toyou_len = length(area.maxtoyou)
  723.     newtoyou_len = length(area.maxnewtoyou)
  724.     pad_len = msg_len + 1 + 1 + toyou_len + 1 /* A space + '()' */
  725.     if fromyou? then do 
  726.         fromyou_len = length(area.maxfromyou)
  727.         newfromyou_len = length(area.maxnewfromyou)
  728.         pad_len = pad_len + 1 + fromyou_len   /* A space */
  729.     end
  730. end
  731. else pad_len = msg_len
  732.  
  733. totallen = length(msg.out_11) + 1
  734. width = 3
  735. do while width + pad_len < totallen
  736.     width = width + 1
  737. end
  738. spaces = makespaces(width)
  739. spaces_minus_one = makespaces(width - 1)  /* '100%' kludge */
  740.  
  741. line.1  =  tosser||' '||msg.out_1||' '||word(sourceline(2), 4)
  742. line.2  =  ''
  743. line.3  =  msg.out_2||' '||start.firstdb
  744.  
  745. line.4  =  msg.out_3||' '||area.totalmsgs
  746. if toyou? then do
  747.     if fromyou? then line.4 = line.4||' ('||area.totaltoyou||' '||msg.out_4||', '||area.totalfromyou||' '||msg.out_5||')'
  748.     else line.4 = line.4||' ('||area.totaltoyou||' '||msg.out_4||')'
  749. end
  750.  
  751. line.5 = ''
  752.  
  753. line.6  =  msg.out_6||' '||start.thisdb
  754. line.7  =  msg.out_7||' '||start.lastdb
  755.  
  756. line.8  =  area.totallogmsgs||' '||msg.out_8
  757. if toyou? then do
  758.     if fromyou? then line.8 = line.8||' ('||area.totallogtoyou||' '||msg.out_4||', '||area.totallogfromyou||' '||msg.out_5||')'
  759.     else line.8 = line.8||' ('||area.totallogtoyou||' '||msg.out_4||')'
  760. end
  761. line.8  =  line.8||' '||replace(msg.out_9, '%s', area.string.0)
  762.  
  763. line.9 = ''
  764.  
  765. line.10 = left(msg.out_10, area.length)||spaces||left('%', 5)||spaces||,
  766.           left(msg.out_11, pad_len + width)||msg.out_12
  767.  
  768. line.11 = ''
  769.  
  770. num = 12                             /* Number of lines in header + 1 */
  771.  
  772. do q = area.string.0 to 1 by -1
  773.     parse var area.string.q _msgs '"' areaname '"' _toyou _fromyou newmsgs newtoyou newfromyou .
  774.  
  775.     if ~allareas? & _msgs = 0 then leave
  776.     _msgs = strip(_msgs)
  777.  
  778.     if toyou? then do
  779.         if fromyou? then do
  780.             youtotal = ' ('||right(_toyou, toyou_len)||' '||right(_fromyou, fromyou_len)||')'
  781.             younew = ' ('||right(newtoyou, newtoyou_len)||' '||right(newfromyou, newfromyou_len)||')'
  782.         end
  783.         else do    
  784.             youtotal = ' ('||right(_toyou, toyou_len)||')'
  785.             younew = ' ('||right(newtoyou, newtoyou_len)||')'
  786.         end
  787.     end
  788.     else do
  789.         youtotal = ''
  790.         younew = ''
  791.     end
  792.  
  793.     line.num = left(strip(areaname), area.length)||spaces_minus_one||,
  794.                format(((_msgs / area.totalmsgs) * 100), 3, 2)||spaces||,
  795.                right(_msgs, msg_len)||youtotal||spaces||,
  796.                right(newmsgs, newmsg_len)||younew
  797.  
  798.     say count(num)
  799.     num = num + 1
  800. end
  801.  
  802. line.0 = num - 1
  803.  
  804. if ~writefile(path.out, line) then call errorexit(msg.err_write||' '||path.out)
  805. return
  806.  
  807.  
  808. /*
  809. ** Generic procedures
  810. */
  811.  
  812. MAKESPACES: procedure
  813. return copies(' ', arg(1))
  814.  
  815.  
  816. COUNT: procedure
  817. return ' '||arg(1)||'9b'x||'A'
  818.  
  819.  
  820. FORMAT: procedure
  821. arg number, before, after
  822.  
  823. /* Reformats the number to NUMERIC DIGITS setting */
  824. num = number + 0
  825.  
  826. /* Return the reformatted number if other options not specified */
  827. if before = '' & after = '' then return num
  828.  
  829. /* Split the number into fraction and integer */
  830. parse var num integer '.' fraction
  831.  
  832. /* Set defaults for non-spec'd arguments */
  833. if before = '' then before = length(integer)
  834. if after = '' then after = length(fraction)
  835.  
  836. /* [before] argument must be at least as long as integer   */
  837. if before < length(integer) then return '**ERROR**'
  838.  
  839. /* add an appropriate value of .5 to number to round it    */
  840. if after ~= length(fraction) then do
  841.     fraction = trunc(('.'||fraction||'0') + ('.'||copies('0', after)||'5'), after)
  842.     /* Numbers created as text strings are still numbers */
  843.     integer = integer + (fraction % 1)
  844.     fraction = substr(fraction, 3)
  845. end
  846. if fraction >= 0 then return right(integer, before)||'.'||fraction
  847. else return right(integer, before)
  848.  
  849.  
  850. /*  
  851. ** copyfile(sourcefile, destfile) 
  852. */ 
  853. COPYFILE: procedure
  854. parse arg from, to , mode
  855.  
  856. sz = word(statef(from), 2)
  857.  
  858. call open('s', from, 'r')
  859.  
  860. if upper(mode) = 'A' then call open('d', to, 'a')
  861. else call open('d', to, 'w')
  862.  
  863. do (sz % 65535) + 1      
  864.     call writech('d', readch('s', 65535))
  865. end
  866.  
  867. call close('d')
  868. call close('s')
  869. return
  870.  
  871.  
  872. /*
  873. ** Replace(string, old, new)
  874. */
  875. REPLACE: procedure
  876. parse arg src, old, new
  877. str = ''
  878. do while src ~= ''
  879.   chk = pos(old, src)
  880.   parse var src pre (old) src
  881.   str = str||pre
  882.   if chk > 0 then str = str||new
  883. end
  884. return str
  885.  
  886.  
  887. /*
  888. ** Use while developing...
  889. */
  890. SYNTAX:
  891. ERROR:
  892. trace o
  893. err = rc ; line = sigl
  894. if datatype(err, 'n') then do
  895.     errline = 'Error '||err||': '||errortext(err)||'0a'x||'in line '||line
  896.     sayit? = 1
  897.     if show('p', 'rexx_ced') then do
  898.         parse source . . filename .
  899.         options results
  900.         address 'rexx_ced'
  901.         'cedtofront'
  902.         'ow' filename
  903.         'jump to line' line
  904.         'okay1' errline
  905.         sayit? = 0
  906.     end
  907.     else say errline
  908. end
  909. exit
  910.